﻿using System;
using System.Drawing;
using System.Media;
using System.Threading;
using System.IO;
using System.Reflection;
using System.Windows.Forms;

namespace Snake_Classic
{
    public partial class Form1 : Form
    {
        private Random rand = new Random();
        private Random Timerand = new Random();
        private int check;
        private Snake snake = new Snake();
        private PlayerNameForm playername;
        private FoodAndBonus food;
        private Wall wall = new Wall();
        private Engine engine;


        private bool left = false;
        private bool right = false;
        private bool down = false;
        private bool up = false;
        private bool pause = true;
        private int score = 0;
        private bool flagForLabel = false;
        private int hideBonus = 300;

        private bool shouldPaintBonus = false;

        public int Score
        {
            get 
            { 
                return score;
            }
            private set 
            { 
                score = value;
            }
        }
        public Form1()
        {
            InitializeComponent();
            DoubleBuffered = true;
            food = new FoodAndBonus(snake, wall);
            engine = new Engine(snake, this);
            pauseLabel.Visible = false;            
        }


        private int score_String;

        private void Form1_Load(object sender, EventArgs e)
        {
            check = Timerand.Next(800, 1000);
            timer1.Enabled = true;
            down = false;
            up = false;
            right = true;
            left = false;
            engine.PlayMusicInGame();
            timer2.Start();
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Space)
            {
                if (pause == true)
                {
                    timer1.Stop();
                    engine.StopMusic();
                    pause = false;
                    pauseLabel.Visible = true;
                }
                else
                {
                    timer1.Start();
                    engine.PlayMusicInGame();
                    pause = true;
                    pauseLabel.Visible = false;
                }
            }
            if (e.KeyData == Keys.Down && up == false)
            {
                down = true;
                up = false;
                right = false;
                left = false;
            }
            if (e.KeyData == Keys.Up && down == false)
            {
                down = false;
                up = true;
                right = false;
                left = false;
            }
            if (e.KeyData == Keys.Right && left == false)
            {
                down = false;
                up = false;
                right = true;
                left = false;
            }
            if (e.KeyData == Keys.Left && right == false)
            {
                down = false;
                up = false;
                right = false;
                left = true;
            }
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            //paint food and snake on a form
            food.DrawFood(e.Graphics);
            snake.DrawSnake(e.Graphics);
            wall.DrawWall(e.Graphics);
            if (shouldPaintBonus)
            {
                food.DrawBonus(e.Graphics);
            }
            timer4.Start();
            if (flagForLabel)
            {
                timer4.Stop();
                startLabel.Visible = false;
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            engine.StopMusic();
            timer1.Stop();
            const string message = "Are you sure that you would like to qiute the game?";
            const string caption = "Quite";
            var result = MessageBox.Show(message, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            // If the no button was pressed
            if (result == DialogResult.Yes)
            {
                // cancel the closure of the form
                e.Cancel = false;
                Application.Exit();
            }
            else
            {
                e.Cancel = true;
                timer1.Start();
                engine.PlayMusicInGame();
            }            
        }
        
        /// <summary>
        /// restart the game when snake is dead
        /// </summary>
        public void ChangeSpeed(int score)
        {
            if (score > 0 && score == 500)
            {
                timer1.Interval -= 25;
                SnakeSpeedLabel.Text = "Higher";
            }
            if (score > 500 && score == 1000)
            {
                timer1.Interval -= 25;
                SnakeSpeedLabel.Text = "More high";
            }
            if (score > 1000 && score == 1500)
            {
                timer1.Interval -= 25;
                SnakeSpeedLabel.Text = "High";
            }
            if (score > 1500 && score == 2000)
            {
                timer1.Interval -= 25;
                SnakeSpeedLabel.Text = "Super high";
            }
        }

        public void Restart()
        {

            timer1.Enabled = false;
            MessageBox.Show("Oops! Snake is dead. Your score " + score_String + " ", "Snake");
            playername = new PlayerNameForm(Score);
            playername.ShowDialog();
            snakeScoreLabel.Text = "0";
            snake = new Snake();
        }


        private void timer1_Tick(object sender, EventArgs e)
        {
            snakeScoreLabel.Text = score.ToString();
            if (down)
            {
                snake.MoveDown();
            }
            if (up)
            {
                snake.MoveUp();
            }
            if (right)
            {
                snake.MoveRight();
            }
            if (left)
            {
                snake.MoveLeft();
            }
            for (int i = 0; i < snake.SnakeRec.Length; i++)
            {
                if (snake.SnakeRec[i].IntersectsWith(food.FoodRectangleImage))
                {
                    score += 20;
                    score_String = score;
                    snake.GrowSnake();
                    food.SetFoodLocation();
                    SnakeLengthLabel.Text = snake.SnakeRec.Length.ToString();
                    ChangeSpeed(score);

                }
                else if (snake.SnakeRec[i].IntersectsWith(food.bonusImage))
                {
                    score += 100;
                    score_String = score;
                    snake.GrowSnake();
                    food.StartLocation();
                    SnakeLengthLabel.Text = snake.SnakeRec.Length.ToString();
                    ChangeSpeed(score);
                }
            }
            engine.Collision();
            this.Invalidate();
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            check--;
            if (check == 0)
            {
                shouldPaintBonus = true;
                check = Timerand.Next(1000, 1700);
                food.SetBonusLocation();
                timer3.Start();
            }
        }

        private void timer3_Tick(object sender, EventArgs e)
        {
            hideBonus--;
            if (hideBonus == 0)
            {
                timer3.Stop();
                shouldPaintBonus = false;
                hideBonus = 600;
            }
        }

        private void timer4_Tick(object sender, EventArgs e)
        {
            startLabel.Visible = false;
            flagForLabel = true;
        }
    }
}
